/**
 * 安全存储管理器
 * 提供加密存储、过期管理和安全访问控制
 */
import { SimpleCrypto } from "./crypto"

/**
 * 存储配置选项
 */
export const STORAGE_OPTIONS = {
  ENCRYPTION_LEVEL: {
    NONE: 'none',
    BASIC: 'basic',
    STRICT: 'strict'
  },
  STORAGE_TYPE: {
    LOCAL: 'localStorage',
    SESSION: 'sessionStorage'
  },
  DEFAULT_EXPIRATION: 24 * 60 * 60 * 1000, // 24小时
  SENSITIVE_KEYS: ['token', 'accessToken', 'refreshToken', 'password', 'userInfo', 'credentials', 'apiKey', 'secret']
}

/**
 * 安全存储类
 */
export class SecureStorage {
  constructor(options = {}) {
    this.crypto = new SimpleCrypto(options.secretKey)
    this.keyPrefix = options.keyPrefix || 'secure_'
    this.defaultExpiration = options.defaultExpiration || STORAGE_OPTIONS.DEFAULT_EXPIRATION
    this.defaultStorageType = options.storageType || STORAGE_OPTIONS.STORAGE_TYPE.LOCAL
    this.defaultEncryption = options.encryption || STORAGE_OPTIONS.ENCRYPTION_LEVEL.BASIC
  }

  /**
   * 存储数据
   * @param {string} key - 存储键
   * @param {any} value - 存储值
   * @param {object} options - 存储选项
   */
  setItem(key, value, options = {}) {
    try {
      const config = {
        encrypt: options.encrypt ?? this.shouldEncrypt(key),
        expiration: options.expiration || this.defaultExpiration,
        storageType: options.storageType || this.defaultStorageType,
        encryptionLevel: options.encryptionLevel || this.defaultEncryption
      }

      const storageData = {
        value: value,
        timestamp: Date.now(),
        expiration: config.expiration,
        encrypted: config.encrypt,
        version: '1.0'
      }

      let serializedData = JSON.stringify(storageData)

      if (config.encrypt && config.encryptionLevel !== STORAGE_OPTIONS.ENCRYPTION_LEVEL.NONE) {
        serializedData = this.crypto.encrypt(serializedData)
      }

      const storage = this.getStorage(config.storageType)
      const storageKey = this.keyPrefix + key

      storage.setItem(storageKey, serializedData)
    } catch (error) {
      console.error('安全存储失败:', error)
      throw new Error(`存储 ${key} 失败: ${error.message}`)
    }
  }

  /**
   * 获取数据
   * @param {string} key - 存储键
   * @param {any} defaultValue - 默认值
   * @returns {any} 存储的值或默认值
   */
  getItem(key, defaultValue = null) {
    try {
      let data = this.getFromStorage(key, STORAGE_OPTIONS.STORAGE_TYPE.LOCAL)
      if (!data) {
        data = this.getFromStorage(key, STORAGE_OPTIONS.STORAGE_TYPE.SESSION)
      }

      if (!data) {
        return defaultValue
      }

      if (this.isExpired(data)) {
        this.removeItem(key)
        return defaultValue
      }

      return data.value
    } catch (error) {
      if (import.meta.env.DEV) {
        console.error('获取安全存储失败:', error)
      }
      return defaultValue
    }
  }

  /**
   * 从指定存储获取数据
   * @param {string} key - 存储键
   * @param {string} storageType - 存储类型
   * @returns {object|null} 存储数据对象
   */
  getFromStorage(key, storageType) {
    try {
      const storage = this.getStorage(storageType)
      const storageKey = this.keyPrefix + key
      const rawData = storage.getItem(storageKey)

      if (!rawData) {
        return null
      }

      let serializedData = rawData
      try {
        const decrypted = this.crypto.decrypt(rawData)
        if (decrypted && decrypted.startsWith('{')) {
          serializedData = decrypted
        }
      } catch (decryptError) {
        // 解密失败，使用原始数据
      }

      let storageData
      try {
        storageData = JSON.parse(serializedData)
      } catch (parseError) {
        // 解析失败，清除损坏的数据
        if (import.meta.env.DEV) {
          console.warn(`解析存储数据失败，清除: ${key}`, parseError)
        }
        storage.removeItem(storageKey)
        return null
      }

      if (!this.isValidStorageData(storageData)) {
        if (import.meta.env.DEV) {
          console.warn(`无效的存储数据结构: ${key}`)
        }
        storage.removeItem(storageKey)
        return null
      }

      return storageData
    } catch (error) {
      console.error(`从${storageType}获取数据失败:`, error)
      return null
    }
  }

  /**
   * 删除数据
   * @param {string} key - 存储键
   */
  removeItem(key) {
    try {
      const storageKey = this.keyPrefix + key
      localStorage.removeItem(storageKey)
      sessionStorage.removeItem(storageKey)
    } catch (error) {
      if (import.meta.env.DEV) {
        console.error('删除存储失败:', error)
      }
    }
  }

  /**
   * 清空所有安全存储数据
   */
  clear() {
    try {
      const storages = [localStorage, sessionStorage]

      storages.forEach((storage) => {
        const keysToRemove = []

        for (let i = 0; i < storage.length; i++) {
          const key = storage.key(i)
          if (key && key.startsWith(this.keyPrefix)) {
            keysToRemove.push(key)
          }
        }

        keysToRemove.forEach((key) => storage.removeItem(key))
      })
    } catch (error) {
      console.error('清空存储失败:', error)
    }
  }

  /**
   * 清理过期数据
   */
  cleanExpired() {
    const keys = this.getAllKeys()
    let cleanedCount = 0

    keys.forEach((key) => {
      try {
        const data =
          this.getFromStorage(key, STORAGE_OPTIONS.STORAGE_TYPE.LOCAL) ||
          this.getFromStorage(key, STORAGE_OPTIONS.STORAGE_TYPE.SESSION)

        if (data && this.isExpired(data)) {
          this.removeItem(key)
          cleanedCount++
        }
      } catch (error) {
        if (import.meta.env.DEV) {
          console.error(`清理过期数据失败: ${key}`, error)
        }
      }
    })

    return cleanedCount
  }

  /**
   * 获取所有存储的键
   * @returns {string[]} 存储键列表
   */
  getAllKeys() {
    const keys = new Set()
    const storages = [localStorage, sessionStorage]

    storages.forEach((storage) => {
      for (let i = 0; i < storage.length; i++) {
        const key = storage.key(i)
        if (key && key.startsWith(this.keyPrefix)) {
          keys.add(key.substring(this.keyPrefix.length))
        }
      }
    })

    return Array.from(keys)
  }

  /**
   * 判断是否应该加密
   * @param {string} key - 存储键
   * @returns {boolean} 是否需要加密
   */
  shouldEncrypt(key) {
    return STORAGE_OPTIONS.SENSITIVE_KEYS.some((sensitiveKey) =>
      key.toLowerCase().includes(sensitiveKey.toLowerCase())
    )
  }

  /**
   * 检查数据是否过期
   * @param {object} storageData - 存储数据对象
   * @returns {boolean} 是否过期
   */
  isExpired(storageData) {
    if (!storageData.expiration) {
      return false
    }
    return Date.now() > storageData.timestamp + storageData.expiration
  }

  /**
   * 验证存储数据结构
   * @param {any} data - 数据对象
   * @returns {boolean} 是否有效
   */
  isValidStorageData(data) {
    return (
      data &&
      typeof data === 'object' &&
      'value' in data &&
      'timestamp' in data &&
      typeof data.timestamp === 'number'
    )
  }

  /**
   * 获取存储对象
   * @param {string} storageType - 存储类型
   * @returns {Storage} 存储对象
   */
  getStorage(storageType) {
    switch (storageType) {
      case STORAGE_OPTIONS.STORAGE_TYPE.SESSION:
        return sessionStorage
      case STORAGE_OPTIONS.STORAGE_TYPE.LOCAL:
      default:
        return localStorage
    }
  }
}

// 默认实例
export const secureStorage = new SecureStorage()
